<?php
/**
 * Application bootstrap, old-school PHP style
 *
 * @author    Mon Zafra <monzee at gmail>
 * @copyright (c)2009 Mon Zafra
 * @license   http://monzee.wordpress.com/license New BSD
 * @version   $Id: bootstrap.php 38 2009-02-18 17:12:39Z monzee $
 */

date_default_timezone_set('Asia/Manila');

$old_paths = explode(PATH_SEPARATOR, get_include_path());
$paths_to_prepend = array(path_to('library'));
$paths_to_append = array(path_to('application/models'));
$new_paths = array_merge($paths_to_prepend, $old_paths, $paths_to_append);

$new_paths = array_map('realpath', array_unique($new_paths));
set_include_path(implode(PATH_SEPARATOR, $new_paths));

require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();

/**
 * Set front controller options, register bootstrapper
 *
 * @staticvar bool $initialized Has this function been called already?
 * @param bool $reinitialize Initialize again for some reason?
 * @return void
 */
function init($reinitialize = false)
{
    static $initialized = false;

    if ($initialized && !$reinitialize) {
        return;
    }

    $functions = array('setup_routes', 'setup_database', 'setup_plugins',
        'setup_controllers', 'setup_view');

    front()->throwExceptions(true) // turn this off in production!
           ->setControllerDirectory(path_to('application/controllers'))
           ->addModuleDirectory(path_to('application/modules'))
           ->registerPlugin(new Mz_Bootstrapper($functions));

    $initialized = true;
}

/**
 * Set named routes here
 */
function setup_routes()
{

}

/**
 * Set default Zend_Db_Table adapter
 */
function setup_database()
{
    if (null === Zend_Db_Table_Abstract::getDefaultAdapter()) {
        $adapter = Zend_Db::factory('PDO_SQLITE', array('dbname' => path_to('./development.sqlite')));
        Zend_Db_Table_Abstract::setDefaultAdapter($adapter);
    }
}

/**
 * Register plugins
 */
function setup_plugins()
{
    // true == autodiscover modules with preRoute() methods from the currently
    // defined module directory. see the notes in the comments in the class
    Mz_Module_Initializer::startMvc(true);
}

/**
 * Set controller directory, register modules, action helpers and paths
 */
function setup_controllers()
{
    Zend_Controller_Action_HelperBroker::addPath(path_to('application/controllers/helpers'), 'Action');

    // i had problems with _redirect() prepending the base url twice without the
    // the following line. i'm not sure if this is the proper solution.
    Zend_Controller_Action_HelperBroker::getStaticHelper('Redirector')->setPrependBase(false);
}

/**
 * Setup ViewRenderer, Layout, and View, register view helper paths
 */
function setup_view()
{
    $renderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
    $renderer->initView();

    $view = $renderer->view;
    /* @var $view Zend_View_Abstract */
    $view->addHelperPath(path_to('application/views/helpers'), 'View')
         ->doctype(Zend_View_Helper_Doctype::XHTML1_TRANSITIONAL);
}

/*
 * UTILITY FUNCTIONS :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: ::
 */

/**
 * Get or set the front controller
 *
 * @param mixed $set_to Front controller instance to store. If null, uses
 *              Zend_Controller_Front singleton
 * @return Zend_Controller_Front
 */
function front($set_to = null)
{
    static $front;
    if (null !== $set_to) {
        $front = $set_to;
    } else if (null === $front) {
        $front = Zend_Controller_Front::getInstance();
    }

    return $front;
}

/**
 * Load config, return value from loaded config
 *
 * @staticvar Zend_Config $config Stored Zend_Config object
 * @param string             $key    Config key to get
 * @param string|Zend_Config $file   Config file name or Zend_Config instance
 * @param bool               $reload Reload file or overwrite stored config?
 * @return <type>
 */
function config($key = null, $file = 'config.ini', $reload = false)
{
    static $config;
    if (null === $config || $reload) {
        if ($file instanceof Zend_Config) {
            $config = $file;
        } else {
            $file = path_to($file);
            $config = new Zend_Config_Ini($file);
        }
    }

    if (null === $key) {
        return $config;
    } else {
        return $config->$key;
    }
}

/**
 * Return a path/file relative to the path of the bootstrap
 *
 * It is recommended to put the bootstrap file in the project root directory so
 * there would be no need to use '..' in the paths passed to this function.
 *
 * @staticvar string $base_path Path where the bootstrap is
 * @param string $file
 * @return string
 */
function path_to($file = null)
{
    static $base_path;
    if (empty($base_path)) {
        $base_path = realpath(dirname(__FILE__));
    }

    $ret = $base_path;
    if (!empty($file)) {
        $file = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, trim($file, '/\\'));
        $ret .= DIRECTORY_SEPARATOR . $file;
    }

    return $ret;
}

/**
 * Dispatch request
 *
 * @return mixed
 */
function run()
{
    init();
    return front()->dispatch();
}
